//
// Created by pzw on 24-3-24.
//

#include <csignal>
#include "PseudoCont.h"

template<typename T, size_t N>
std::array<T, N> PseudoCont::std_array() {
    using namespace std;
    array<T, N> array{};
    return array;
}

template<size_t N>
std::bitset<N> PseudoCont::std_bitset() {
    std::bitset<N> bitset = std::bitset<N>();
    for (int i = 0; i < bitset.size(); ++i) {
        bitset.set(i, PseudoCont::randomInt(0, 1));
    }
    return bitset;
}

template<size_t N>
void PseudoCont::std_bitset_reinit(std::bitset<N> &bitset) {
    for (int i = 0; i < bitset.size(); ++i) {
        bitset.set(i, PseudoCont::randomInt(0, 1));
    }
}

static void signalHandler(int signum) {
    std::cout << "捕获到信号 (" << signum << "): 段错误，程序即将退出。" << std::endl;
    // 清理并关闭
    // 执行紧急保存操作
#if 0
    exit(signum);
#endif
}

template<size_t N>
std::vector<bool> PseudoCont::std_vector_bool() {
#define SIGSEGV_ERR 1
#if SIGSEGV_ERR == 0
    signal(SIGSEGV, signalHandler);
    std::vector<bool> vbool(0);
#elif SIGSEGV_ERR == 1
    std::vector<bool> vbool(N);
#endif
    try {
        for (int i = 0; i < N; ++i) {
            vbool[i] = PseudoCont::randomInt(0, 1);
        }
    } catch (const std::exception &e) {
        std::cout << "std_vector_bool: e = " << e.what() << std::endl;
    } catch (...) {
        std::cout << "std_vector_bool: e = Unknown Err" << std::endl;
    }
    return vbool;
}

template<typename T, typename U>
std::pair<T, U> PseudoCont::std_pair() {
    return std::pair<T, U>();
}

template<typename T, typename U>
std::pair<T, U> PseudoCont::std_make_pair(T first, U second) {
    return std::make_pair(first, second);
}

template<typename... Tps>
std::tuple<Tps...> PseudoCont::std_tuple() {
    return std::tuple<Tps...>();
}

template<typename... Tps>
std::tuple<Tps...> PseudoCont::std_make_tuple(Tps... tps) {
    return std::tuple<Tps...>(tps...);
}


int PseudoCont_main() {
    std::array<int, 10> array = PseudoCont::std_array<int, 10>();
    std::vector<int> vs{0, 1, 2, 3, 4, 5, 6, 7};
    std::copy(vs.begin(), vs.end(), array.begin());
    std::cout << "PseudoCont_main: array = {" << std::endl;
    int index = 0;
    for (auto it = array.begin(); it != array.end(); it++) {
        if (index == array[0]) {
            std::cout << "    " << *it << ", ";
        } else if (index == array.size() - 1) {
            std::cout << *it;
        } else {
            std::cout << *it << ", ";
        }
        index++;
    }
    std::cout << std::endl << "}" << std::endl;

    std::bitset<8> bitset = PseudoCont::std_bitset<8>();
    std::cout << "PseudoCont_main: bitset = " << bitset << std::endl;
    bitset.reset();
    std::cout << "PseudoCont_main: reset-bitset = " << bitset << std::endl;
    PseudoCont::std_bitset_reinit(bitset);
    std::cout << "PseudoCont_main: std_bitset_reinit-bitset = " << bitset << std::endl;
    bitset >>= 8;
    std::cout << "PseudoCont_main: >>=-bitset = " << bitset << std::endl;
    bitset.flip();
    std::cout << "PseudoCont_main: flip-bitset = " << bitset << std::endl;

    std::vector<bool> vsbool = PseudoCont::std_vector_bool<8>();
    std::cout << "PseudoCont_main: vsbool = {" << std::endl;
    for (int i = 0; i < vsbool.size(); i++) {
        std::cout << vsbool[i];
    }
    std::cout << std::endl << "}" << std::endl;

    std::pair<int, std::string> pair = PseudoCont::std_pair<int, std::string>();
    pair.first = 0x0004;
    pair.second = "Acc Mode";
    const std::pair<int, const char *> &pair2 = PseudoCont::std_make_pair(0x0003, "Power Mode");
    std::cout << "PseudoCont_main: pair = { " << pair.first << " : " << pair.second << " }"
              << ", pair2 = { " << pair2.first << " : " << pair2.second << " }" << std::endl;

    auto tuple = PseudoCont::std_make_tuple<int, char, double, long, std::string>(1, '2', 3.0, 4L, "5");
    std::tuple<int, char, double, long, std::string> tuple2 = PseudoCont::std_tuple<int, char, double, long, std::string>();
    std::cout << "PseudoCont_main: tuple(3,4) = {" << std::get<3>(tuple)
              << ", " << std::get<4>(tuple) << "}" << std::endl;
    tuple.swap(tuple2);
    std::cout << "PseudoCont_main: tuple2 swap tuple(3,4) = {" << std::get<3>(tuple)
              << ", " << std::get<4>(tuple) << "}" << std::endl;
    std::cout << "PseudoCont_main: tuple2(3,4) = {" << std::get<3>(tuple2)
              << ", " << std::get<4>(tuple2) << "}" << std::endl;

    return 0;
}
